package multidraw.tools;

import java.awt.Point;
import java.awt.event.MouseEvent;

import multidraw.model.ControlPair;
import multidraw.model.DrawingCanvasModel;
import multidraw.model.Shape;
import multidraw.model.TwoEndBoundaryShape;
import multidraw.model.TwoEndShape;
import multidraw.model.commands.MoveShapeCommand;
import multidraw.model.commands.ResizeShapeCommand;



enum SelectorState {
    NONE, MOVE, RESIZE 
}

public class SelectorTool extends Tool {
	//protected DrawingCanvasModel myModel;
	
	//protected boolean isMoving;
	protected SelectorState state;
	
	protected Point startingMousePosition;
	protected Point currentMousePosition;
	protected ControlPair controlPair = null;
		
	protected Shape outlineShape = null;
	
	public SelectorTool(DrawingCanvasModel model) {
		this.myModel = model;
	}
	
	public Shape getShape() {
		return outlineShape;
	}

	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		myModel.selectObject(e.getX(), e.getY());
		System.out.println(e.getX() + " - " + myModel.getSelectedObjectIndex());
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		if (myModel.getSelectedObjectIndex() >= 0) {
			//check if the point is inside the bound rectangle.
			//if yes then move on, else return
			//check if this near one of the corners
			//if yes then turn the resize flag on.
			//else turn the moving flag on.
			//write down the starting position as the current position.
			Shape s = myModel.getSelectedObject();
			if (s != null && s instanceof TwoEndBoundaryShape) {
				TwoEndBoundaryShape s1 = (TwoEndBoundaryShape) s;
				if ((s instanceof TwoEndShape) && s.isNearControlPoint(e.getPoint())) {
					state = SelectorState.RESIZE;
					controlPair = s1.getControlPoints(e.getPoint());
					startingMousePosition = e.getPoint();
					currentMousePosition = e.getPoint();
					outlineShape = s.getOutlineShape();					
				} else if (s1 != null && s1.isInsideBoundaryRectangle(e.getPoint())) {
					//isMoving = true;
					state = SelectorState.MOVE;
					startingMousePosition = e.getPoint();
					currentMousePosition = e.getPoint();
					//TODO: check the frequency of mouse pressed calls.
					outlineShape = s.getOutlineShape();
				}
			}
			myModel.notifyObservers();
		}
	}

	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		//finally move the object
		if (outlineShape != null && outlineShape instanceof TwoEndBoundaryShape) {			
			if (state.equals(SelectorState.MOVE)) {
				//myModel.getSelectedObject().translate(startingMousePosition, e.getPoint());
				MoveShapeCommand command = new MoveShapeCommand(myModel.
						getSelectedObject().getShapeID(), startingMousePosition,
						e.getPoint());
				myModel.addCommand(command);
				
				state = SelectorState.NONE;
				outlineShape = null;
				startingMousePosition = null;
				currentMousePosition = null;
				//myModel.notifyObservers();
			} else if (state.equals(SelectorState.RESIZE)) {
				TwoEndShape selectedObject = (TwoEndShape) myModel.getSelectedObject();
				Point movingPoint = (Point) controlPair.getSecondPoint().clone();
				movingPoint.translate(e.getPoint().x - startingMousePosition.x, 
						e.getPoint().y - startingMousePosition.y);
				//selectedObject.updateShapeInfo(controlPair.getFirstPoint(), movingPoint);
				ResizeShapeCommand command = new ResizeShapeCommand(
						selectedObject.getShapeID(), controlPair.getFirstPoint(),
						movingPoint);
				myModel.addCommand(command);
				
				state = SelectorState.NONE;
				outlineShape = null;
				startingMousePosition = null;
				currentMousePosition = null;
				myModel.notifyObservers();				
			}
		}
		 
	}

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		//update the outline shape
		if (outlineShape != null && state.equals(SelectorState.MOVE)) {
			//Shape originalShape = myModel.getSelectedObject();
			System.out.println("is Moving");
			System.out.println(currentMousePosition);
			System.out.println(e.getPoint());
			outlineShape.translate(currentMousePosition, e.getPoint());
			currentMousePosition = e.getPoint();
			myModel.notifyObservers();
		} else if (outlineShape != null && state.equals(SelectorState.RESIZE)) {
			System.out.println("is Resizing");
			System.out.println(currentMousePosition);
			System.out.println(e.getPoint());
			if (controlPair != null) {
				Point movingPoint = (Point) controlPair.getSecondPoint().clone();
				movingPoint.translate(e.getPoint().x - startingMousePosition.x, 
						e.getPoint().y - startingMousePosition.y);
				TwoEndShape os = (TwoEndShape) outlineShape;
				os.updateShapeInfo(controlPair.getFirstPoint(), movingPoint);
				currentMousePosition = e.getPoint();
				myModel.notifyObservers();
			}
			
		}
	}

	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}	
}
